package com.ruoyi.system.service.impl;

import com.github.pagehelper.PageHelper;
import com.itextpdf.text.pdf.BaseFont;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.user.TemplateException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FastDFSUtil;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.mongodb.Users;
import com.ruoyi.system.mapper.CompeWorkScroingRecordMapper;
import com.ruoyi.system.mapper.SysEventsPostedMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mongo.AllSchoolDao;
import com.ruoyi.system.mongo.SysUserDao;
import com.ruoyi.system.mongo.WorksDao;
import com.ruoyi.system.service.*;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author HP
 * @Date 2021/3/3
 * @Description TODO
 */
@Slf4j
@Service
public class CompeWorkScroingRecordServiceImpl implements CompeWorkScroingRecordService {
    @Autowired
    private CompeWorkScroingRecordMapper compeWorkScroingRecordMapper;

    @Autowired
    private SysEventsPostedMapper sysEventsPostedMapper;
    @Autowired
    private WorksDao worksDao;

    @Autowired
    private ISysUsersService sysUsersService;

    @Autowired
    private AllSchoolDao allSchoolDao;

    @Autowired
    private ISysEventsPostedService iSysEventsPostedService;

    @Autowired
    private FastDFSUtil fastDFSUtil;

    @Autowired
    private ISysCertificateService iSysCertificateService;

    @Autowired
    private ISysCertificateTeacherService iSysCertificateTeacherService;

    @Autowired
    private ISysCertificateSchoolService iSysCertificateSchoolService;

    @Autowired
    private ISysOrganizationService sysOrganizationService;
    //根目录
    private String rootPath = System.getProperty("user.dir");
    @Value("${pdf_temp_path}")
    private String pdfTempPath;
    @Value("${pdf_temp_folder}")
    private String TEMPLATE;//模板存储路径
    @Value("${ftl_temp_path}")
    private String CONTRACT;

    private static final String PDFNAME = "pdfDemo";//pdf文件名
    private static final String HTMLNAME = "pdfDemo";//html文件名
    @Autowired
    private SysUserDao sysUserDao;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 根据传过来的证书信息生成学生证书
     * @param sysCertificateAlls
     */
    @Override
    public void generateSchoolCertificates(List<SysCertificateAll> sysCertificateAlls) throws TemplateException {
        //循环取出证书信息
        for (SysCertificateAll sysCertificateAll : sysCertificateAlls) {
            //获取当前时间转换字符串用于证书编号
            Date date=new Date();
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            String format = sdf.format(date);

            //填充教师证书信息
            SysCertificateSchool sysCertificateSchool=new SysCertificateSchool();
            sysCertificateSchool.setSchoolid(allSchoolDao.queryByNames(sysCertificateAll.getSchooName()).get_id());
            sysCertificateSchool.setSchoolrName(sysCertificateAll.getSchooName());
            sysCertificateSchool.setEpid(sysCertificateAll.getEpid());
            sysCertificateSchool.setOrganizationid(sysCertificateAll.getOrganizationid());
            //获取当前时间转换字符串用于证书编号
            sysCertificateSchool.setIssuetime(format);
            //查询该教师是否已经颁发过证书
            Integer count = iSysCertificateSchoolService.queryCertificateSchoolIsNull(sysCertificateSchool);
            //如果没颁发过这颁发老师证书否则则不颁发
            if(count==0){
                //添加教师证书信息
                iSysCertificateSchoolService.saveSysCertificateSchool(sysCertificateSchool);
            }


        }
    }

    /**
     * 根据赛事id获取生成学校证书所需要的所有信息
     * @param epid
     * @return
     */
    @Override
    public List<SysCertificateAll> querySysCertificateAllSchoolByEpid(Integer epid) {
        return compeWorkScroingRecordMapper.querySysCertificateAllSchoolByEpid(epid);
    }



    /**
     * 根据证书信息生成教师证书
     * @param sysCertificateAlls
     */
    @Override
    public void generateTeacherCertificates(List<SysCertificateAll> sysCertificateAlls) throws TemplateException {
        //循环取出证书信息
        for (SysCertificateAll sysCertificateAll : sysCertificateAlls) {
            //获取当前时间转换字符串用于证书编号
            Date date=new Date();
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
            String format = sdf.format(date);

            //填充教师证书信息
            SysCertificateTeacher sysCertificateTeacher=new SysCertificateTeacher();
            sysCertificateTeacher.setTeacher(sysCertificateAll.getTeacherId());
            sysCertificateTeacher.setTname(sysCertificateAll.getDirectTeacher());
            sysCertificateTeacher.setEpid(sysCertificateAll.getEpid());
            sysCertificateTeacher.setOrganizationid(sysCertificateAll.getOrganizationid());
            //获取当前时间转换字符串用于证书编号
            sysCertificateTeacher.setIssuetime(format);
            //查询该教师是否已经颁发过证书
            Integer count = iSysCertificateTeacherService.queryCertificateTeacherIsNull(sysCertificateTeacher);
            //如果没颁发过这颁发老师证书否则则不颁发
            if(count==0){
                //添加教师证书信息
                iSysCertificateTeacherService.saveSysCertificateTeacher(sysCertificateTeacher);
            }


        }
    }


    /**
     * 在排名公布后根据赛事id生成老师证书
     * @param epid
     */
    @Override
    public List<SysCertificateAll> querySysCertificateAllTeacherByEpid(Integer epid) {
        return compeWorkScroingRecordMapper.querySysCertificateAllTeacherByEpid(epid);
    }


    /**
     * 在排名公布后根据赛事id生成学生证书
     * @param epid
     * @return
     */
    @Override
    public List<SysCertificateAll> querySysCertificateAllStudentByEpid(Integer epid) {
        return compeWorkScroingRecordMapper.querySysCertificateAllStudentByEpid(epid);
    }


    /**
     * 根据赛事id查询是否存在没有排名公布的信息
     * @param epid
     * @return
     */
    @Override
    public Integer queryCompeWorkScroingRecordByPublicStatus(Integer epid) {
        return compeWorkScroingRecordMapper.queryCompeWorkScroingRecordByPublicStatus(epid);
    }

    /**
     * 根据证书信息生成学生证书
     * @param sysCertificateAlls
     */
    @Override
    public void generateStudentCertificates(List<SysCertificateAll> sysCertificateAlls) throws TemplateException {
        //添加学生证书信息
        //循环取出证书信息
        for (SysCertificateAll sysCertificateAll : sysCertificateAlls) {
            //填充学生证书信息
            SysCertificate sysCertificate=new SysCertificate();
            sysCertificate.setName(sysCertificateAll.getRealname());
            sysCertificate.setStuid(sysCertificateAll.getSid());
            sysCertificate.setTitle(sysCertificateAll.getTitle());
            sysCertificate.setProduction(sysCertificateAll.getWork_id());
            sysCertificate.setEpid(sysCertificateAll.getEpid());
            sysCertificate.setAwards(sysCertificateAll.getRanking());
            sysCertificate.setTname(sysCertificateAll.getDirectTeacher());
            sysCertificate.setTeacher(sysCertificateAll.getTeacherId());
            sysCertificate.setOrganizationid(sysCertificateAll.getOrganizationid());
            sysCertificate.setOrganizationname(sysCertificateAll.getOrganizationname());
            sysCertificate.setEventgroup(sysCertificateAll.getEventgroup());
            //获取当前时间转换字符串用于证书编号
            Date date=new Date();
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-M-dd");
            String format = sdf.format(date);
            sysCertificate.setIssuetime(format);
            //查询是否有重复的学生证书信息
            Integer count = iSysCertificateService.queryCertificateIsNull(sysCertificate);
            //如果没有则添加否则不添加
            if(count==0){
                iSysCertificateService.saveSysCertificates(sysCertificate);
            }
        }
    }

    /**
     * 查询是否评审过比赛
     * @param compeWorkScroingRecord
     * @return
     */
    @Override
    public CompeWorkScroingRecord queryCompeWorkScroingRecordIsNull(CompeWorkScroingRecord compeWorkScroingRecord) {
        return compeWorkScroingRecordMapper.queryCompeWorkScroingRecordIsNull(compeWorkScroingRecord);
    }

    /**
     * 获取最后添加Id
     * @return
     */
    @Override
    public Integer readLastInsertScoringId() {
        return compeWorkScroingRecordMapper.readLastInsertScoringId();
    }

    @Override
    public List<CompeWorkScroingRecord> queryCompetitionRankingAnnouncement(CompeWorkScroingRecord compeWorkScroingRecord,Integer pageNum,Integer pageSize) {
        if (pageNum!=null&&pageSize!=null){
            PageHelper.startPage((pageNum / pageSize) + 1,pageSize);
        }
        List<CompeWorkScroingRecord> compeWorkScroingRecords = compeWorkScroingRecordMapper.queryCompetitionRankingAnnouncement(compeWorkScroingRecord);
        return compeWorkScroingRecords;
    }

    /**
     * 教师端根据教师id查询已评审作品的信息
     * @param compeWorkScroingRecord
     * @return
     */
    public List<CompeWorkScroingRecord> queryWorksRecordByTid(CompeWorkScroingRecord compeWorkScroingRecord) {

        Users users = sysUserDao.queryUserById(compeWorkScroingRecord.getTid());
//        if (users != null&& users.getIsAdmin() == 1) {
//            return compeWorkScroingRecordMapper.queryWorksRecordBySchool(compeWorkScroingRecord);
//        } else {
            return compeWorkScroingRecordMapper.queryWorksRecordByTid(compeWorkScroingRecord);
//        }
    }

    /**
     * 管理后台根据用户id查询已评审作品的信息
     * @param compeWorkScroingRecord
     * @return
     */
    public List<CompeWorkScroingRecord> queryWorksRecordByAdmin(CompeWorkScroingRecord compeWorkScroingRecord) {
        //获取当前登录者的账户
        SysUser sysUser = sysUserMapper.selectUserById(Long.parseLong(compeWorkScroingRecord.getTid()));
        boolean isAdmin = false; //是否为管理员
        if (sysUser!= null ) {
            //获取当前用户的角色
            List<SysRole> roles = sysUser.getRoles();;
            if (roles != null) {
                for (SysRole role : roles) {
                    //如果当前用户有管理员角色
                    if ("common".equals(role.getRoleKey()) ) {
                        isAdmin = true;
                        break;
                    }
                }
            }
        }
        if (isAdmin) { //如果是后台管理员
            return compeWorkScroingRecordMapper.queryWorksRecordByAdmin(compeWorkScroingRecord);
        } else {
            return compeWorkScroingRecordMapper.queryWorksRecordByTid(compeWorkScroingRecord);
        }
    }

    @Override
    public void updateRanking(CompeWorkScroingRecord compeWorkScroingRecord) {
        compeWorkScroingRecordMapper.updateRanking(compeWorkScroingRecord);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updatePublicStatus(CompeWorkScroingRecord compeWorkScroingRecord) throws Exception {
        compeWorkScroingRecordMapper.updatePublicStatus(compeWorkScroingRecord);
        SyseEventsPosted syseEventsPosted = iSysEventsPostedService.selectById(compeWorkScroingRecord.getCompe_id());
        String event_step = "决赛";
        if (StringUtils.isEmpty(syseEventsPosted.getProgressStatus())) {
            if ("4".equals(syseEventsPosted.getProgressStatus())) {
                event_step = "初赛";
            } else if ("5".equals(syseEventsPosted.getProgressStatus())) {
                event_step = "复赛";
            }
        }
        compeWorkScroingRecord.setEvent_step(event_step);
        //查询获奖名次
        List<CompeWorkScroingRecord> compeWorkScroingRecords=compeWorkScroingRecordMapper.queryPrize(compeWorkScroingRecord);
        Integer epsponsorid = syseEventsPosted.getEpsponsorid();
        SysOrganization sysOrganization = sysOrganizationService.querySysOrganizationById(epsponsorid);
        if (sysOrganization == null || sysOrganization.getSeal() == null) {
            throw new Exception("请先到'机构管理'中添加主办方的印章！");
        }
        //这里是选择某个模板
        String templateName = "template";
        String baseUrl = System.getProperty("user.dir");
        baseUrl = baseUrl.replaceAll("\\\\", "/");
        for (CompeWorkScroingRecord compeWorkScroingRecord1 : compeWorkScroingRecords) {
            if (StringUtils.isBlank(compeWorkScroingRecord1.getClassName())){
                compeWorkScroingRecord1.setClassName("-");
            }
            if (StringUtils.isBlank(compeWorkScroingRecord1.getRealname())) {
                compeWorkScroingRecord1.setRealname("-");
            }
            if (StringUtils.isBlank(compeWorkScroingRecord1.getDirectTeacher())) {
                compeWorkScroingRecord1.setDirectTeacher("-");
            }
            if (StringUtils.isBlank(compeWorkScroingRecord1.getTitle())){
                compeWorkScroingRecord1.setTitle("-");
            }
        }
        log.info("compeWorkScroingRecords == " + compeWorkScroingRecords);
        //组织数据填充到模板中
        Map<String, Object> paramMap = new HashMap<String, Object>();
        //这里是给具体的某些字段赋值
        paramMap.put("name", syseEventsPosted.getEptitle());
        paramMap.put("compeWorkScroingRecords", compeWorkScroingRecords);
        paramMap.put("epsponsor", syseEventsPosted.getEpsponsor());
        paramMap.put("eporganizer", syseEventsPosted.getEporganizer()==null?"-":syseEventsPosted.getEporganizer());
        paramMap.put("seal", sysOrganization.getSeal());
        /*
         * 生成的pdf文件的路径
         */
        String pdfPath = "";
        //生成pdf文件
        contractHandler(templateName, paramMap);
        pdfPath = fastDFSUtil.uploadFile(new File(System.getProperty("user.dir") + pdfTempPath));
        SyseEventsPosted syseEventsPosted1=new SyseEventsPosted();
        syseEventsPosted1.setRankingpath(pdfPath);
        syseEventsPosted1.setEpid(syseEventsPosted.getEpid());
        iSysEventsPostedService.updateRankingpath(syseEventsPosted1);
        //更改比赛状态为结束状态
        sysEventsPostedMapper.editEpstate(compeWorkScroingRecord.getCompe_id());

    }

    @Override
    public List<CompeWorkScroingRecord> queryPrize(int compe_id, String event_step) {
        CompeWorkScroingRecord query = new CompeWorkScroingRecord();
        query.setCompe_id(compe_id);
        query.setEvent_step(event_step);
        return compeWorkScroingRecordMapper.queryPrize(query);
    }


    /**
     * 评分完成后添加评分信息
     * @param compeWorkScroingRecord
     */
    @Transactional
    @Override
    public void saveCompeWorkScroingRecord(CompeWorkScroingRecord compeWorkScroingRecord) {
        //插入
        if (compeWorkScroingRecord.getScoring_id() == null) {
            compeWorkScroingRecordMapper.saveCompeWorkScroingRecord(compeWorkScroingRecord);
        } else {//修改评分信息
            compeWorkScroingRecordMapper.updateCompeWorkScroingRecord(compeWorkScroingRecord);
        }


    }


    public void contractHandler(String templateName,
                                Map<String, Object> paramMap) throws Exception {
        // 获取本地模板存储路径、合同文件存储路径
        String templatePath = rootPath+TEMPLATE;
        String contractPath = rootPath+CONTRACT;
        // 组装html和pdf合同的全路径URL
        String localHtmlUrl = contractPath + HTMLNAME + ".html";
        String localPdfPath = contractPath + "/";
        // 判断本地路径是否存在如果不存在则创建
        File localFile = new File(localPdfPath);
        if (!localFile.exists()) {
            localFile.mkdirs();
        }
        String localPdfUrl = localFile + "/" + PDFNAME + ".pdf";
        templateName = templateName + ".ftl";
        htmHandler(contractPath, templateName, localHtmlUrl, paramMap);// 生成html合同
        pdfHandler(localHtmlUrl, localPdfUrl);// 根据html合同生成pdf合同
        deleteFile(localHtmlUrl);// 删除html格式合同

        System.out.println("PDF生成成功");
    }

    /**
     * 生成HTML格式合同
     * @param templatePath
     * @param templateName
     * @param htmUrl
     * @param paramMap
     * @throws Exception
     */
    private static void htmHandler(String templatePath, String templateName,
                                   String htmUrl, Map<String, Object> paramMap) throws Exception {
        Configuration cfg = new Configuration();
        cfg.setDefaultEncoding("UTF-8");
        cfg.setDirectoryForTemplateLoading(new File(templatePath));

        Template template = cfg.getTemplate(templateName);

        File outHtmFile = new File(htmUrl);

        Writer out = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(outHtmFile)));
        template.process(paramMap, out);

        out.close();
    }

    /**
     * 生成PDF格式合同
     * @param htmUrl
     * @param pdfUrl
     * @throws Exception
     * @throws IOException
     */
    private static void pdfHandler(String htmUrl, String pdfUrl)
            throws Exception, IOException {
        File htmFile = new File(htmUrl);
        File pdfFile = new File(pdfUrl);

        String url = htmFile.toURI().toURL().toString();

        OutputStream os = new FileOutputStream(pdfFile);

        ITextRenderer renderer = new ITextRenderer();

        //renderer.getSharedContext().setBaseURL("file:/"+"E:/IdeaProjects/demo/src/main/resources/image/");

        renderer.setDocument(url);


        ITextFontResolver fontResolver = renderer
                .getFontResolver();

        try {
            fontResolver.addFont(System.getProperty("user.dir")+"\\ruoyi-admin\\src\\main\\resources\\zhengshu\\font\\simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (Exception e) {
            e.printStackTrace();
        }

        renderer.layout();
        try {
            renderer.createPDF(os);
        } catch (Exception e) {
            e.printStackTrace();
        }
        os.close();
    }

    /**
     * 删除HTML文件
     * @param fileUrl
     */
    private static void deleteFile(String fileUrl) {
        File file = new File(fileUrl);
        file.delete();
    }
}
